﻿using System;
using System.Xml;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;
using Ro.AssistFunction.BackNodeInfo;
using Ro.AssistFunction.OutputManage;
using Ro.Common.RoArgs;
using Ro.Common.RoInterface.UserType;
using Ro.DriverEvent.FindElement;

/*
 * Todo 2017-3-23 更新 预先判断Element是否为空，不为空才可以使用
 */

namespace Ro.DriverEvent.IntegrationFun
{
    /// <summary>
    /// 构造函数
    /// AreEqual和AreNotEqual本质是相同的，仅在处理结果进行了不同分拆
    /// </summary>
    public class WebEqual
    {
        /// <summary>
        /// 返回值，返回执行结果
        /// todo 3-27更新成WebActionResult
        /// </summary>
        public WebActionResult BackResult;


        /// <summary>
        /// 构造函数实体
        /// 进行执行
        /// </summary>
        /// <param name="sigNode">AreEqual或AreNotEqual节点</param>
        public WebEqual(XmlNode sigNode)
        {
            //返回值
            WebActionResult back = new WebActionResult();

            ExtractNeedInfo extractNeedInfo = new ExtractNeedInfo();

            //预期值
            string expValue = extractNeedInfo.ExtractInnerText(sigNode, "web:ExpectedValue");

            //转换为正常的输入值
            ArgsIntoValue argsIntoValue = new ArgsIntoValue(expValue);
            expValue = argsIntoValue.BackValue;

            //实际类型
            string acttype = extractNeedInfo.ExtractAttributeValue(sigNode.LastChild, "xsi:type");
            //提取元素
            string value = extractNeedInfo.ExtractAttributeValue(sigNode.LastChild, "web:RoWebElementID");

            //提取超时
            TimeSpan timeout = extractNeedInfo.ExtractTimeout(sigNode);

            //构造函数初始化，获取元素
            FindWebElement findElement = new FindWebElement(value, timeout);
            IWebElement ele = findElement.WebElement;

            try
            {
                //如果元素为空，反馈结果为空
                if (ele != null)
                {
                    //循环实际值类型
                    string actvalue;
                    switch (acttype)
                    {
                        case "web:Browser.IsPageLoaded":
                            IJavaScriptExecutor jsExecutor = RoTestObject.WebTestObject as IJavaScriptExecutor;
                            string com = (string) jsExecutor?.ExecuteScript("return document.readyState");
                            //写入实际值
                            actvalue = (com == "complete").ToString();
                            back = StrResOut(expValue, actvalue, sigNode.Name, value);

                            break;

                        case "web:Browser.Title":
                            actvalue = RoTestObject.WebTestObject.Title;
                            back = StrResOut(expValue, actvalue, sigNode.Name, value);

                            break;

                        case "web:Browser.Url":
                            actvalue = RoTestObject.WebTestObject.Url;
                            back = StrResOut(expValue, actvalue, sigNode.Name, value);
                            break;

                        case "web:RoWebElement.Displayed":
                            actvalue = ele.Displayed.ToString();
                            back = StrResOut(expValue, actvalue, sigNode.Name, value);
                            break;

                        case "web:RoWebElement.Enabled":
                            actvalue = ele.Enabled.ToString();
                            back = StrResOut(expValue, actvalue, sigNode.Name, value);
                            break;

                        case "web:RoWebElement.Selected":
                            actvalue = ele.Selected.ToString();
                            back = StrResOut(expValue, actvalue, sigNode.Name, value);
                            break;

                        case "web:RoWebElement.Text":
                            //todo 验证web:RoWebElement.Text时，还需要再验证一次本节点的下一个兄弟节点

                            //如果是input控件
                            if (ele.TagName == "input")
                            {
                                //查找下一个同级节点
                                IWebElement temp = ele.FindElement(By.XPath("following-sibling::input"));
                                if (temp != null)
                                {
                                    //点击操作，相当于给定焦点
                                    Actions action = new Actions(RoTestObject.WebTestObject);
                                    action.MoveToElement(temp).Perform();
                                    //action.Click(temp).Perform();
                                    actvalue = temp.GetAttribute("value");
                                }
                                else
                                {
                                    actvalue = ele.Text;
                                }
                            }
                            //等待验证的是非input控件
                            else
                            {
                                actvalue = ele.GetAttribute("textContent");
                                //actvalue = ele.Text;
                            }

                            back = StrResOut(expValue, actvalue, sigNode.Name, value);
                            break;

                        case "web:RoWebElement.GetAttribute":
                            //提取元素
                            string attype = extractNeedInfo.ExtractAttributeValue(sigNode.LastChild, "web:Name");
                            actvalue = ele.GetAttribute(attype);
                            back = StrResOut(expValue, actvalue, sigNode.Name, value);
                            break;
                    }
                }
                else
                {
                    back = BackActionResult.BackWebResult(false, value, "WebEqual操作遭遇查找元素失败，获取元素为null"); //结果
                }
            }
            // 抛出异常

            catch (Exception e)
            {
                back = BackActionResult.BackWebResult(false, value, "验证值等/不等操作遭遇System异常"); //结果
                ExceptionOutPut.SystemExceptionOut("WebEqual", e);
            }

            //返回构造值
            BackResult = back;
        }


        /// <summary>
        /// 针对string属性判断的输出语句
        /// </summary>
        /// <param name="expValue">实际预期值</param>
        /// <param name="actvalue">实际真实值</param>
        /// <param name="typename">euqal or not euqal</param>
        /// <param name="value">控件名称</param>
        private WebActionResult StrResOut(string expValue, string actvalue, string typename, string value)
        {
            WebActionResult back;

            if (typename == "web:WaitUntil.AreEqual")
            {
                if (expValue == actvalue)
                {
                    back = BackActionResult.BackWebResult(true, value, "验证值等/不等验证成功，预期值：" + expValue + " ,实际值：" + actvalue); //结果
                }
                else
                {
                    back = BackActionResult.BackWebResult(false, value, "验证值等/不等验证失败，预期值：" + expValue + " ,实际值：" + actvalue); //结果
                }
            }
            else
            {
                if (expValue != actvalue)
                {
                    back = BackActionResult.BackWebResult(true, value, "验证值等/不等验证成功，预期值：" + expValue + " ,实际值：" + actvalue); //结果
                }
                else
                {
                    back = BackActionResult.BackWebResult(false, value, "验证值等/不等验证失败，预期值：" + expValue + " ,实际值：" + actvalue); //结果
                }
            }
            return back;
        }
    }
}

